package com.example.flatlafdemo.components.table;

import com.example.flatlafdemo.DemoUtilities;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.net.URI;
import java.util.logging.Logger;

public class TableDemo extends JPanel {
    static final Logger logger = Logger.getLogger(TableDemo.class.getName());

    private OscarTableModel oscarModel;

    private JTable oscarTable;
    private Color[] rowColors;

    public TableDemo() {
        initPanel();
        start();
    }

    public void start() {
        if (oscarModel.getRowCount() == 0) {
            loadData("/oscars.xml");
        }
    }

    private void initPanel() {
        oscarModel = new OscarTableModel();
        oscarTable = new JTable(oscarModel);
        // </snip>

        // </snip>Set JTable display properties
        oscarTable.setColumnModel(createColumnModel());
        oscarTable.setAutoCreateRowSorter(true);
        oscarTable.setRowHeight(26);
        oscarTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
        oscarTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        oscarTable.setIntercellSpacing(new Dimension(0, 0));
        // </snip>

        // <snip>Initialize preferred size for table's viewable area
        Dimension viewSize = new Dimension();
        viewSize.width = oscarTable.getColumnModel().getTotalColumnWidth();
        viewSize.height = 10 * oscarTable.getRowHeight();
        oscarTable.setPreferredScrollableViewportSize(viewSize);
        // </snip>

        // <snip>Customize height and alignment of table header
        JTableHeader header = oscarTable.getTableHeader();
        header.setPreferredSize(new Dimension(30, 26));
        TableCellRenderer headerRenderer = header.getDefaultRenderer();
        if (headerRenderer instanceof JLabel) {
            ((JLabel) headerRenderer).setHorizontalAlignment(JLabel.CENTER);
        }
        // </snip>

        JScrollPane scrollpane = new JScrollPane(oscarTable);
        this.setLayout(new BorderLayout());
        add(scrollpane, BorderLayout.CENTER);
    }

    protected TableColumnModel createColumnModel() {
        DefaultTableColumnModel columnModel = new DefaultTableColumnModel();

        TableCellRenderer cellRenderer = new OscarCellRenderers.RowRenderer(getTableRowColors());

        TableColumn column = new TableColumn();
        column.setModelIndex(OscarTableModel.YEAR_COLUMN);
        column.setHeaderValue("Year");
        column.setPreferredWidth(26);
//        column.setCellRenderer(new OscarCellRenderers.YearRenderer(getTableRowColors()));
        columnModel.addColumn(column);

        column = new TableColumn();
        column.setModelIndex(OscarTableModel.CATEGORY_COLUMN);
        column.setHeaderValue("Award Category");
        column.setPreferredWidth(100);
//        column.setCellRenderer(cellRenderer);
        columnModel.addColumn(column);

        column = new TableColumn();
        column.setModelIndex(OscarTableModel.MOVIE_COLUMN);
        column.setHeaderValue("Movie Title");
        column.setPreferredWidth(180);
        HyperlinkCellRenderer hyperlinkRenderer = new OscarCellRenderers.MovieRenderer(
                new IMDBLinkAction(), true, getTableRowColors());
        hyperlinkRenderer.setRowColors(getTableRowColors());
//        column.setCellRenderer(hyperlinkRenderer);
        columnModel.addColumn(column);

        column = new TableColumn();
        column.setModelIndex(OscarTableModel.PERSONS_COLUMN);
        column.setHeaderValue("Nominees");
        column.setPreferredWidth(120);
//        column.setCellRenderer(new OscarCellRenderers.NomineeRenderer(getTableRowColors()));
        columnModel.addColumn(column);

        return columnModel;
    }

    private Color[] getTableRowColors() {
        if (rowColors == null) {
            rowColors = new Color[2];
            rowColors[0] = UIManager.getColor("Table.background");
            rowColors[1] = new Color((int) (rowColors[0].getRed() * .9),
                    (int) (rowColors[0].getGreen() * .9),
                    (int) (rowColors[0].getBlue() * .9));
        }
        return rowColors;
    }

    public void loadData(String dataPath) {
        OscarDataParser parser = new OscarDataParser() {
            @Override
            protected void addCandidate(OscarCandidate candidate) {
                oscarModel.add(candidate);
            }
        };

        parser.parseDocument(TableDemo.class.getResource(dataPath));
    }

    private class IMDBLinkAction extends AbstractAction {

        public void actionPerformed(ActionEvent event) {
            int row = ((Integer) event.getSource()).intValue();
            OscarCandidate candidate = oscarModel.getCandidate(oscarTable
                    .convertRowIndexToModel(row));

            try {
                URI imdbURI = candidate.getIMDBMovieURI();
                if (imdbURI == null) {
                    String imdbString = IMDBLink.getMovieURIString(
                            candidate.getMovieTitle(), candidate.getYear());
                    if (imdbString != null) {
                        imdbURI = new URI(imdbString);
                        candidate.setIMDBMovieURI(imdbURI);
                    }
                }
                if (imdbURI != null) {
                    DemoUtilities.browse(imdbURI);
                } else {
                    String message = "Unable to locate IMDB URL for" + candidate.getMovieTitle();
                    JOptionPane.showMessageDialog(TableDemo.this, message, "IMDB Link",
                            JOptionPane.INFORMATION_MESSAGE);
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}
